`include "cpu_def.vh"

module ex_wb_reg(
  input clk,
  input rst,

  input [3:0] stall,
  input [2:0] flush,

  input        ex_out_valid       ,
  input [31:0] ex_out_pc          ,
  input [31:0] ex_out_alu_result  ,
  input [63:0] ex_out_div_rs      ,
  input        ex_out_wr_mem      ,
  input        ex_out_write_rf    ,
  input [ 4:0] ex_out_rf_waddr    ,
  input [ 2:0] ex_out_sel_rf_wdata,
  input [ 1:0] ex_out_write_hl    ,
  input        ex_out_sel_hl_wdata,

  input [ 2:0] ex_out_cp0_wsel    ,
  input [ 4:0] ex_out_cp0_wreg_num,
  input        ex_out_cp0_wen     ,
  input [31:0] ex_out_cp0_wdata   ,
  input [31:0] ex_out_cp0_rdata   ,
  input        ex_out_ft_tlbre    ,
  input        ex_out_ft_tlbi     ,
  input        ex_out_sys         ,
  input        ex_out_brk         ,
  input        ex_out_ov          ,
  input        ex_out_adel        ,
  input        ex_out_ades        ,
  input        ex_out_tlbrel      ,
  input        ex_out_tlbres      ,
  input        ex_out_tlbil       ,
  input        ex_out_tlbis       ,
  input        ex_out_tlbm        ,
  input        ex_out_ft_adel     ,
  input        ex_out_ri          ,
  input        ex_out_int         ,
  input [31:0] ex_out_badvaddr    ,
  input        ex_out_eret        ,
  input        ex_out_bd          ,
  input        ex_out_tlbp        ,
  input        ex_out_tlbr        ,
  input        ex_out_tlbwi       ,
  input        ex_out_tlbwr       ,

  output reg        wb_in_valid       ,
  output reg [31:0] wb_in_pc          ,
  output reg [31:0] wb_in_alu_result  ,
  output reg [63:0] wb_in_div_rs      ,
  output reg        wb_in_wr_mem      ,
  output reg        wb_in_write_rf    ,
  output reg [ 4:0] wb_in_rf_waddr    ,
  output reg [ 2:0] wb_in_sel_rf_wdata,
  output reg [ 1:0] wb_in_write_hl    ,
  output reg        wb_in_sel_hl_wdata,

  output reg [ 2:0] wb_in_cp0_wsel    ,
  output reg [ 4:0] wb_in_cp0_wreg_num,
  output reg        wb_in_cp0_wen     ,
  output reg [31:0] wb_in_cp0_wdata   ,
  output reg [31:0] wb_in_cp0_rdata   ,
  output reg        wb_in_ft_tlbre    ,
  output reg        wb_in_ft_tlbi     ,
  output reg        wb_in_sys         ,
  output reg        wb_in_brk         ,
  output reg        wb_in_ov          ,
  output reg        wb_in_adel        ,
  output reg        wb_in_ades        ,
  output reg        wb_in_tlbrel      ,
  output reg        wb_in_tlbres      ,
  output reg        wb_in_tlbil       ,
  output reg        wb_in_tlbis       ,
  output reg        wb_in_tlbm        ,
  output reg        wb_in_ft_adel     ,
  output reg        wb_in_ri          ,
  output reg        wb_in_int         ,
  output reg [31:0] wb_in_badvaddr    ,
  output reg        wb_in_eret        ,
  output reg        wb_in_bd          ,
  output reg        wb_in_tlbp        ,
  output reg        wb_in_tlbr        ,
  output reg        wb_in_tlbwi       ,
  output reg        wb_in_tlbwr       
);

  always@(posedge clk) begin
    if (rst || flush[2]) begin
      wb_in_valid <= 1'b0;
    // end else if (stall[2] && !stall[3]) begin
    //   wb_in_valid <= 1'b0;
    end else if (!stall[2]) begin
      wb_in_valid <= ex_out_valid;
    end

    if (!stall[2]) begin
      wb_in_pc           <= ex_out_pc          ;
      wb_in_alu_result   <= ex_out_alu_result  ;
      wb_in_div_rs       <= ex_out_div_rs      ;
      wb_in_wr_mem       <= ex_out_wr_mem      ;
      wb_in_write_rf     <= ex_out_write_rf    ;
      wb_in_rf_waddr     <= ex_out_rf_waddr    ;
      wb_in_sel_rf_wdata <= ex_out_sel_rf_wdata;
      wb_in_write_hl     <= ex_out_write_hl    ;
      wb_in_sel_hl_wdata <= ex_out_sel_hl_wdata;

      wb_in_cp0_wsel     <= ex_out_cp0_wsel    ;
      wb_in_cp0_wreg_num <= ex_out_cp0_wreg_num;
      wb_in_cp0_wen      <= ex_out_cp0_wen     ;
      wb_in_cp0_wdata    <= ex_out_cp0_wdata   ;
      wb_in_cp0_rdata    <= ex_out_cp0_rdata   ;
      wb_in_ft_tlbre     <= ex_out_ft_tlbre    ;
      wb_in_ft_tlbi      <= ex_out_ft_tlbi     ;
      wb_in_sys          <= ex_out_sys         ;
      wb_in_brk          <= ex_out_brk         ;
      wb_in_ov           <= ex_out_ov          ;
      wb_in_adel         <= ex_out_adel        ;
      wb_in_ades         <= ex_out_ades        ;
      wb_in_tlbrel       <= ex_out_tlbrel      ;
      wb_in_tlbres       <= ex_out_tlbres      ;
      wb_in_tlbil        <= ex_out_tlbil       ;
      wb_in_tlbis        <= ex_out_tlbis       ;
      wb_in_tlbm         <= ex_out_tlbm        ;
      wb_in_ft_adel      <= ex_out_ft_adel     ;
      wb_in_ri           <= ex_out_ri          ;
      wb_in_int          <= ex_out_int         ;
      wb_in_badvaddr     <= ex_out_badvaddr    ;
      wb_in_eret         <= ex_out_eret        ;
      wb_in_bd           <= ex_out_bd          ;
      wb_in_tlbp         <= ex_out_tlbp        ;
      wb_in_tlbr         <= ex_out_tlbr        ;
      wb_in_tlbwi        <= ex_out_tlbwi       ;
      wb_in_tlbwr        <= ex_out_tlbwr       ;
    end
  end


endmodule